package com.vichat.agent.security;

import com.vichat.agent.util.JwtUtil;
import com.vichat.common.cache.RedisHelper;
import com.vichat.common.util.Configure;
import com.vichat.common.util.CookieUtil;
import com.vichat.common.util.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * JwtFilter强制执行单点登录。如果JWT令牌不存在(未经验证)，则重定向到认证。 如果JWT令牌存在(已验证)，则提取用户标识并转发请求。
 */
@Component
public class JwtFilter extends OncePerRequestFilter {

    protected static final Logger logger = LoggerFactory.getLogger(JwtFilter.class);
    private String jwtTokenCookieName;
    private String signingKey;

    public JwtFilter() {
        this.jwtTokenCookieName = Configure.getString("jwt.token.cookie.name");
        this.signingKey = Configure.getString("signing.key");
    }

    @Override
    public void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        boolean isPass = true;
        String token = httpServletRequest.getHeader("agent_token");
        if (StringUtils.isBlank(token)) {
            token = httpServletRequest.getParameter("agent_token");
        }
        if (StringUtils.isBlank(token)) {
            token = CookieUtil.getValue(httpServletRequest, "agent_token");
        }
        String uid = JwtUtil.getSubject(httpServletRequest, token, this.signingKey);//access_token解析出uid
        if (uid == null) {
            isPass = false;//uid为空则不通过
        } else {
            String jwtFRD = RedisHelper.get("AGENT_LOGIN_TOKEN:" + uid);
            if (!StringUtils.equals(token, jwtFRD)) {
                isPass = false;//与redis不一致则不通过
            }
            String userJson = RedisHelper.getAgentUser(NumberUtils.toLong(uid));
            if (StringUtils.isBlank(userJson)) {//uid在redis中无用户信息则不通过
                isPass = false;
            }
        }
        if (isPass) {
            httpServletRequest.setAttribute("uid", uid);
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        } else {
            CookieUtil.clear(httpServletResponse,"agent_token",null);
            String noAuthUrl = getUrl(httpServletRequest)+"/agent/noAuth";
            httpServletResponse.sendRedirect(noAuthUrl);
        }
    }


    private String getUrl(HttpServletRequest request){
         String serverName = request.getServerName();
        int port = request.getServerPort();
        StringBuilder sbd = new StringBuilder();
        // 强制使用https
        sbd.append("http://").append(serverName);
        if(port != 80 ) {
            sbd.append(":").append(port).append("/");
        }
        return sbd.toString();
    }
}
